package com.cqw.mq;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.annotation.Configuration;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * @Author: caoqingwen
 * @CreateTime: 2021-09-10 19:28
 * @Description: 消息监听
 */
@Configuration
@Slf4j
public class MqListenerConfig implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {


    @Resource
    private RabbitTemplate rabbitTemplate;


    @PostConstruct
    public void initRabbitTemplate() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    /**
     * 消息发送到交换机后回调，就是确认消息是否到了MQ，异步监听
     *
     * @param correlationData 包含消息的唯一标识对象
     * @param ack             是否到达交换机
     * @param cause           没有到达交换机的原因
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        //correlationData{"future":{"cancelled":false,"done":true},"id":"a6bab2fa-964a-4201-b0e0-535386f1c701"}
        System.out.println("correlationData" + JSON.toJSONString(correlationData));
        System.out.println("cause" + cause);
        if (ack) {
            System.out.println("到达交换机");
            //操作数据库，将correlationId这条消息状态改为投递成功

            //correlationId  这个id需要在发送消息的时候设置
        } else {
            System.out.println("消息发送失败");
            log.error("消息投递失败，ID为：{}，错误信息：{}", correlationData.getId(), cause);
        }
    }


    /**
     * 消息由交换机到队列
     *
     * @param message    消息体
     * @param replyCode  回调的状态
     * @param replyText  文本
     * @param exchange   交换机的名称
     * @param routingKey 路由名
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        System.out.println(JSON.toJSONString(message) + "达到队列失败" + replyCode + " " + replyText + "交换机为：" + exchange + ",路由Key为：" + routingKey);

        //操作数据库 将correlationId的数据状态改为投递失败

    }
}
